package conversion.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import conversion.bean.User;
import conversion.service.EmailService;
import conversion.service.UserService;

import conversion.utils.JwtUtil;
import conversion.utils.PasswordUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ResourceLoader;
import org.springframework.data.redis.core.RedisTemplate;
//import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.UUID;
import java.util.regex.Pattern;

import org.springframework.web.multipart.MultipartFile;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@Slf4j
@Controller
@RequestMapping("/account")
public class UserController {

    /**
     * 注入userService用于操作user数据
     */
    @Resource
    UserService userService;

    /**
     * 注入redisTemplate用于缓存数据
     */
    @Resource
    private RedisTemplate<String, String> redisTemplate;

//    @Resource
//    private PasswordEncoder passwordEncoder;

    @Resource
    private ResourceLoader resourceLoader;

    @Resource
    JwtUtil jwtUtil;

    /**
     * 注入emailService用于操作邮箱相关操作
     */
    @Resource
    EmailService emailService;

    // 指定保存图片的目录路径
    @Value("${upload.directory}")
    private String uploadDirectory;

    private static final String PASSWORD_PATTERN = "^(?=.*[A-Za-z])(?=.*\\d|.*[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?])(?=.*[A-Z]).{8,}$";
    private static final Pattern passwordPattern = Pattern.compile(PASSWORD_PATTERN);

    private static final String EMAIL_PATTERN = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$";
    private static final Pattern emailPattern = Pattern.compile(EMAIL_PATTERN);


    @PostMapping("/uploadImage")
    @ResponseBody
    public String uploadImage(@RequestParam("image") MultipartFile file,
                              HttpSession session,
                              HttpServletResponse response) {
        // 检查是否选择了文件
        if (file.isEmpty()) {
//            redirectAttributes.addFlashAttribute("message", "请选择一个文件进行上传");
            log.info("文件为空");
            return "noFile";
        }
        try {
            //从session中获取user用户
            User user = (User) session.getAttribute("user");
            //获取image文件后缀
            String extension = StringUtils.getFilenameExtension(file.getOriginalFilename());
            // 使用用户的UUID生成唯一的文件名
            String fileName = user.getUUID() + "." + extension;
            log.info(fileName);

            // 获取静态资源目录的绝对路径
            String staticResourcesPath = resourceLoader.getResource("classpath:/static/").getFile().getAbsolutePath();
            // 创建目标文件路径
            Path targetPath = Paths.get(staticResourcesPath, uploadDirectory, fileName);
            // 将文件保存到目标路径
            Files.copy(file.getInputStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);

            //更新user.avatar的文件名
            user.setAvatar(fileName);
            //通过userService更新数据库的数据
            userService.updateUserByUUID(user);
            //调用generateTokenAndSetCookie将新user生成token放回前端
            generateTokenAndSetCookie(user,response);

        } catch (IOException e) {
            e.printStackTrace();
        }

        return "success";
    }

//    /**
//     * 注销用户
//     * @param session  清楚session里的数据
//     * @return 返回首页
//     */
//    @GetMapping("/exit")
//    public String exit(HttpSession session,HttpServletResponse response){
//        session.invalidate();
//        deleteCookie(response, "token");
//        return "index";
//    }

//    /**
//     * 检查用户名是否存在
//     * @param map 用来存放用户数据的map集合
//     * @return 如果存在，返回exists，反之noExists
//     */
//    @PostMapping("/checkUsername")
//    @ResponseBody
//    public String checkUsername(@RequestBody Map<String,String> map){
//        if (userService.getUserByUsername(map.get("username")) == null) {
//            return "noExists";
//        }else {
//            return "exists";
//        }
//
//    }

    /**
     * 检查用户名是否存在,返回用户名
     * @param map 用来存放用户数据的map集合
     * @return 如果存在，返回exists，反之noExists
     */
    @PostMapping("/verifyAccount")
    @ResponseBody
    public String verifyAccount(@RequestBody Map<String, String> map){
        if (userService.getUserByUsername(map.get("username")) == null) {
            return "noExists";
        }else {
            return userService.getUserByUsername(map.get("username")).getEmail();
        }

    }


//    @PostMapping("/updateUsername")
//    @ResponseBody
//    public String updateUsername(@RequestBody Map<String,String> map,
//                             HttpSession session){
//        User user = (User)session.getAttribute("user");
//        if (map.get("username")!=null){
//            user.setUsername(map.get("username"));
//            userService.updateUserByUuid(user);
//            session.setAttribute("user",user);
//            log.info(user.toString());
//        }
//        return "success";
//    }
    @PostMapping("/updateUserInfo")
    @ResponseBody
    public String updateUserInfo(@RequestBody User user,
                             HttpSession session,HttpServletResponse response){
        User user1 = (User) session.getAttribute("user");
        //更新user1里的数据
        user1.setUsername(user.getUsername());
        user1.setAddress(user.getAddress());
        user1.setEmail(user.getEmail());
        userService.updateUserByUUID(user1);
//        调用generateTokenAndSetCookie将新user生成token放回前端
        generateTokenAndSetCookie(user1,response);
        return "success";
    }

    /**
     * 发送邮件
     * @param email 目标邮件地址，作为redis存储的key
     */
    @GetMapping("/sendEmail")
    @ResponseBody
    public String sendEmail(@RequestParam("email") String email){
        // 验证邮箱格式
        if (!emailPattern.matcher(email).matches()) {
            return "emailError";
        }
        //判断Email是否重复
        if (userService.findUserByEmail(email) != null){
            //email重复
            return "emailExists";
        }
        log.info("====>请求参数邮箱地址为{}",email);
        // 1.生成4位随机验证码
        // 截取当前时间戳的后四位模拟验证码
        String verificationCode = emailService.getVerificationCode();

        log.info("====>验证码为:{}",verificationCode);
        // 2.存入redis
        // 将传入邮箱地址为key，验证码为value，存入redis中，并设置超时时间为5分钟
        redisTemplate.opsForValue().set(email,verificationCode,5, TimeUnit.MINUTES);
        // 3.编写邮件内容模板
        String emailInfo = "验证码为：" + verificationCode +"，5分钟内有效。";
        // 4.发送验证码到目标邮箱
        emailService.sendEmail( email, "注册验证码", emailInfo);
        return "success";
    }

//    @GetMapping("/sendEmailVerificationCode")
//    @ResponseBody
//    public boolean sendEmailVerificationCode(@RequestParam("email") String email){
//
//        log.info("====>请求参数邮箱地址为{}",email);
//        // 1.生成4位随机验证码
//        // 截取当前时间戳的后四位模拟验证码
//        String verificationCode = emailService.getVerificationCode();
//
//        log.info("====>验证码为:{}",verificationCode);
//        // 2.存入redis
//        // 将传入邮箱地址为key，验证码为value，存入redis中，并设置超时时间为5分钟
//        redisTemplate.opsForValue().set(email,verificationCode,1, TimeUnit.MINUTES);
//        // 3.编写邮件内容模板
//        String emailInfo = "验证码为：" + verificationCode +"，5分钟内有效。";
//        // 4.发送验证码到目标邮箱
//        emailService.sendEmail( email, "注册验证码", emailInfo);
//        return true;
//    }


    @PostMapping("/register")
    @ResponseBody
    public String register(@RequestBody Map<String, String> map){

        String password = map.get("password");
        String email = map.get("email");
        String verificationCode = map.get("verificationCode");

        // 验证密码格式
        if (!passwordPattern.matcher(password).matches()) {
            return "passwordError";
        }
        // 验证邮箱格式
        if (!emailPattern.matcher(email).matches()) {
            return "emailError";
        }
        User user = User.builder()
                .email(email)
                .UUID(UUID.randomUUID().toString())
                .password(PasswordUtils.hashPassword(password))
//                .password(passwordEncoder.encode(password))
                .username(email)
                .avatar("user.jpg")
                .gender(User.Gender.OTHER)
                .build();

        if(redisTemplate.hasKey(email)){
            // 取出对应邮箱地址为key的value值
            String storyCode = redisTemplate.opsForValue().get(user.getEmail());
            // 判断存在redis中的验证码和传入验证码是否相同，相同返回true
            if (verificationCode.equals(storyCode)){
                //添加用户
                userService.addUser(user);
                return "success";
            }else {
                return "verificationCodeError";
            }
        }else {
            return "codeError";
        }

    }

//    @PostMapping("/verificationCode")
//    @ResponseBody
//    public String verificationCode(@RequestBody Map<String, String> map,HttpSession session){
//
//        if(redisTemplate.hasKey(map.get("email"))){
//            // 取出对应邮箱地址为key的value值
//            String storyCode = redisTemplate.opsForValue().get(map.get("email"));
//            // 判断存在redis中的验证码和传入验证码是否相同，相同返回true
//            if (map.get("verificationCode").equals(storyCode)){
//                session.setAttribute("user",userService.findUserByEmail(map.get("email")));
//
//                return "success";
//            }else {
//                return "verificationCodeError";
//
//            }
//        }else {
//            return "codeError";
//        }
//
//    }

//    @PostMapping("/updateEmail")
//    @ResponseBody
//    public String updateEmail(@RequestBody Map<String, String> map,
//                             HttpSession session){
//        User user = (User) session.getAttribute("user");
//        log.info(user.toString());
//
//        if(redisTemplate.hasKey(map.get("email"))){
//            // 取出对应邮箱地址为key的value值
//            String storyCode = redisTemplate.opsForValue().get(map.get("email"));
//            // 判断存在redis中的验证码和传入验证码是否相同，相同返回true
//            if (map.get("verificationCode").equals(storyCode)){
//                user.setEmail(map.get("email"));
//                //更新数据库数据
//                userService.updateUserByUuid(user);
//                //将更新后的数据放进
//                // session
//                session.setAttribute("user",user);
//                return "success";
//            }else {
//                return "verificationCodeError";
//
//            }
//        }else {
//            return "emailError";
//        }
//
//    }



//    @PostMapping("/login")
//    @ResponseBody
//    public Map<String, String> login(@RequestBody Map<String, String> map,
//                                     HttpServletResponse response) {
//        Map<String, String> responseBody = new HashMap<>();
//        String password = map.get("password");
//        String email = map.get("email");
//        User user = userService.findUserByEmail(email);
//
//        if (PasswordUtils.verifyPassword(password, user.getPassword())) {
//
//            user.setPassword(null);
//            // 调用generateTokenAndSetCookie方法来生成 token 和设置 cookie
//            generateTokenAndSetCookie(user, response);
//
////                session.setAttribute("user", user);
//            responseBody.put("success", "登录成功");
//        } else {
//            responseBody.put("error", "用户名或密码错误");
//        }
//        return responseBody;
//    }

    @PostMapping("/updatePassword")
    @ResponseBody
    public String updatePassword(@RequestBody Map<String,String> map,
                               HttpSession session,
                                 HttpServletResponse response){
        String oldPassword = map.get("oldPassword");
        String newPassword = map.get("newPassword");
        User user = (User) session.getAttribute("user");
        User userByEmail = userService.findUserByEmail(user.getEmail());
        if (oldPassword == null){
            return "error";
        }
        //判断当前密码是否错误
        if (PasswordUtils.verifyPassword(oldPassword,userByEmail.getPassword())){
            // 验证密码格式
            if (!passwordPattern.matcher(newPassword).matches()) {
                return "passwordError";
            }
            user.setPassword(PasswordUtils.hashPassword(newPassword));
            userService.updateUserByUUID(user);
            session.invalidate();
            //删除token
            deleteCookie(response, "token");

            return "success";
        }else {
            return "error";
        }
    }

    /**
     * 生成 token 并设置 cookie
     *
     * @param user 用户对象
     * @param response HttpServletResponse 对象
     */
    private void generateTokenAndSetCookie(User user, HttpServletResponse response) {
        try {
            String token = jwtUtil.generateToken(user);

            Cookie cookie = new Cookie("token", token);
            cookie.setMaxAge(1000 * 60 * 60 * 24);  // 设置 cookie 的生命周期（单位：秒），这里设置为 一天
            cookie.setPath("/");  // 设置 cookie 的路径

            response.addCookie(cookie);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除指定名称的 Cookie。
     *
     * @param response HTTP 响应对象
     * @param name     要删除的 Cookie 的名称
     */
    private void deleteCookie(HttpServletResponse response, String name) {
        Cookie cookie = new Cookie(name, "");
        cookie.setMaxAge(0);
        cookie.setPath("/");
        response.addCookie(cookie);
    }

}
